﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.CSharp;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Reflection;

namespace com.huigo.Framework.ServiceUtils.Parser
{
    public class AssemblyTools
    {
        private static Assembly NewAssembly(List<Dictionary<string, string>> serviceList)
        {
            //创建编译器实例。   
            CSharpCodeProvider provider = new CSharpCodeProvider();
            //设置编译参数。   
            CompilerParameters paras = new CompilerParameters();
            paras.GenerateExecutable = false;
            paras.GenerateInMemory = true;

            //创建动态代码。
            StringBuilder classSource = new StringBuilder();
            classSource.Append("public class ServiceModel \n");
            classSource.Append("{\n");

            //创建属性。   
            foreach (KeyValuePair<string, string> kvp in serviceList[0])
            {
                classSource.Append(propertyString(kvp.Key));
            }

            classSource.Append("}");

            System.Diagnostics.Debug.WriteLine(classSource.ToString());

            //编译代码。   
            CompilerResults result = provider.CompileAssemblyFromSource(paras, classSource.ToString());

            //获取编译后的程序集。   
            Assembly assembly = result.CompiledAssembly;

            return assembly;
        }

        private static string propertyString(string propertyName)
        {
            StringBuilder sbProperty = new StringBuilder();
            sbProperty.Append(" private string  _" + propertyName + " ;\n");
            sbProperty.Append(" public string " + "" + propertyName + "\n");
            sbProperty.Append(" {\n");
            sbProperty.Append(" get{   return   _" + propertyName + ";}   \n");
            sbProperty.Append(" set{   _" + propertyName + "   =   value;   }\n");
            sbProperty.Append(" }");
            return sbProperty.ToString();
        }

        public static List<object> GetModelList(List<Dictionary<string, string>> serviceList)
        {
            Assembly assembly = NewAssembly(serviceList);
            List<object> list = new List<object>();
            foreach (Dictionary<string, string> dict in serviceList)
            {
                object Class1 = assembly.CreateInstance("ServiceModel");
                foreach (KeyValuePair<string, string> kvp in dict)
                {
                    ReflectionSetProperty(Class1, kvp.Key, kvp.Value);
                }
                list.Add(Class1);
            }
            return list;
        }

        private static void ReflectionSetProperty(object objClass, string propertyName, string value)
        {
            PropertyInfo[] infos = objClass.GetType().GetProperties();
            foreach (PropertyInfo info in infos)
            {
                if (info.Name == propertyName && info.CanWrite)
                {
                    info.SetValue(objClass, value, null);
                }
            }
        }
    }
}
